import Vue from "vue";
import config from "@r/config";
import { commonParame, requestConfig } from "@r/config/requestConfig";

const { service } = config;

export class Request {
  // 导出的api对象
  static apiLists = {};

  /**
   * @static 处理options
   * @param {Options | string} opts
   * @param {Datas} data
   * @returns {Options}
   * @memberof Request
   */
  static conbineOptions(opts, data, method) {
    typeof opts === "string" && (opts = { url: opts });
    let optionsData = {
      data: { ...commonParame, ...opts.data, ...data },
      method: opts.method || data.method || method || "GET",
      url: `${opts.host || service}${opts.url}`,
    };

    // 是否需要携带token   noToken == true 不需要携带  noToken == false 需要携带
    const _token = this.getToken().token || "";
    if (!data.noToken && _token) {
      optionsData.header = {
        Authorization: "Bearer " + _token,
      };
    }

    // 是否需要自定义在链接后面拼接参数 格式 url/fasdf/sen  urlUserId == true 的时候就会自动拼接
    if (data.urlUserId) {
      optionsData.url = `${optionsData.url}/${this.getToken().id}`;
    }

    // 是否需要在链接后面拼接 格式 url/fasdf/sen   urlId == xx 的时候 会在链接后面拼接url/xx
    if (data.urlId) {
      optionsData.url = `${optionsData.url}/${data.urlId}`;
    }

    return optionsData;
  }

  static getToken() {
    return uni.getStorageSync("userInfo") || {};
  }

  /**
   *
   * @static request请求 基于 uni.request
   * @param {Options} opts
   */
  static async request(opts) {
    let res = await unirequest(opts);

    return res.data;
  }

  /**
   *
   * @static  创建请求函数
   * @param {(Options | string)} opts
   * @returns
   * @memberof Request
   */
  static creatRequests(opts) {
    return async (data = {}, method = "GET") => {
      const _opts = this.conbineOptions(opts, data, method);
      const res = await this.request(_opts);
      return res;
    };
  }

  /**
   *
   * @static 抛出整个项目的api方法
   * @returns
   * @memberof Request
   */
  static getApiList(requestConfig) {
    if (!Object.keys(requestConfig).length) return {};

    Object.keys(requestConfig).forEach((key) => {
      this.apiLists[key] = this.creatRequests(requestConfig[key]);
    });

    return this.apiLists;
  }
}

// 修改uni请求为Promise
const unirequest = (opts) => {
  return new Promise((resolve, reject) => {
    uni.request({
      ...opts,
      success: (res) => {
        resolve(res);
      },
      fail: (error) => {
        reject(error);
      },
    });
  });
};

// 导出
const Api = Request.getApiList(requestConfig);
Vue.prototype.$api = Api;
export default Api;
